|
Server : Apache System : Linux server.mata-lashes.com 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64 User : matalashes ( 1004) PHP Version : 8.1.29 Disable Function : NONE Directory : /home/matalashes/www/wp-content/plugins/security-malware-firewall/lib/CleantalkSP/Common/ |
Upload File : |
<?php
namespace CleantalkSP\Common;
/**
* @psalm-suppress UnusedClass
*/
abstract class Queue
{
/**
* @var string Holds option prefix for system/DB/Storage
*/
protected static $option_prefix = '';
/**
* @var string option name
*/
protected $option_name;
/**
* @var string Name of remote call
*/
public $rc_name = '';
public $queue;
public $unstarted_stage;
/**
* Process identifier
*
* @var int
*/
private $pid;
public function __construct($queue_name, $remote_call_action = '')
{
$this->rc_name = $remote_call_action;
$this->pid = mt_rand(0, mt_getrandmax());
$this->option_name = static::$option_prefix . $queue_name . '_queue';
$queue = $this->getQueue();
if ($queue !== false && isset($queue['stages'])) {
$this->queue = $queue;
} else {
$this->queue = array(
'started' => time(),
'finished' => '',
'stages' => array(),
);
}
}
/**
* Abstract
*
* Get the queue from DB or whatever
*
* @return mixed
*/
abstract public function getQueue();
/**
* Abstract
*
* Refreshes the $this->queue from the DB or whatever
*
*/
abstract public function refreshQueue();
/**
* Abstract
*
* Save the current state of queue in DB or whatever
*
* @param array|null $queue
*
*/
abstract public function saveQueue($queue = null);
/**
* Adding stage to the queue and saving it to DB
*
* @param string $stage_name
* @param array $args
* @param int $accepted_tries
*/
public function addStage($stage_name, $args = array(), $accepted_tries = 3)
{
$this->queue['stages'][] = array(
'name' => $stage_name,
'status' => 'NULL',
'tries' => '0',
'accepted_tries' => $accepted_tries,
'args' => $args,
'pid' => null,
);
$this->saveQueue();
}
/**
* Performs current stage of the queue
* Tries it 3 times for the stage
* Then calling a remote call for the next stage
*
* @return null|string|string[]|bool|array
*/
public function executeStage()
{
global $spbc;
$stage_to_execute = null;
if ($this->hasUnstartedStages()) {
$this->queue['stages'][$this->unstarted_stage]['status'] = 'IN_PROGRESS';
$this->queue['stages'][$this->unstarted_stage]['pid'] = $this->pid;
$this->saveQueue();
usleep(1000);
$this->refreshQueue();
if ($this->queue['stages'][$this->unstarted_stage]['pid'] !== $this->pid) {
return true;
}
$stage_to_execute = &$this->queue['stages'][$this->unstarted_stage];
}
if ($stage_to_execute) {
if (is_callable($stage_to_execute['name'])) {
++$stage_to_execute['tries'];
if (! empty($stage_to_execute['args'])) {
$result = $stage_to_execute['name']($stage_to_execute['args']);
} else {
$result = $stage_to_execute['name']();
}
if (isset($result['error'])) {
$stage_to_execute['status'] = 'NULL';
$stage_to_execute['error'][] = $result['error'];
if (isset($result['update_args']['args'])) {
$stage_to_execute['args'] = $result['update_args']['args'];
}
$this->saveQueue();
$accepted_tries = isset($stage_to_execute['accepted_tries']) ? $stage_to_execute['accepted_tries'] : 3;
if ($stage_to_execute['tries'] >= $accepted_tries) {
$stage_to_execute['status'] = 'FINISHED';
$this->saveQueue();
return $result;
}
return \CleantalkSP\SpbctWP\RemoteCalls::performToHost(
$this->rc_name,
array(
'updating_id' => $spbc->fw_stats['updating_id'],
'stage' => 'Repeat ' . $stage_to_execute['name']
),
array('async')
);
}
if (isset($result['next_stage'])) {
$this->addStage(
$result['next_stage']['name'],
isset($result['next_stage']['args']) ? $result['next_stage']['args'] : array(),
isset($result['next_stage']['accepted_tries']) ? $result['next_stage']['accepted_tries'] : 3
);
}
if (isset($result['next_stages']) && count($result['next_stages'])) {
foreach ($result['next_stages'] as $next_stage) {
$this->addStage(
$next_stage['name'],
isset($next_stage['args']) ? $next_stage['args'] : array(),
isset($result['next_stage']['accepted_tries']) ? $result['next_stage']['accepted_tries'] : 3
);
}
}
unset($stage_to_execute['error']);
$stage_to_execute['status'] = 'FINISHED';
$this->saveQueue();
return $result;
}
return array('error' => $stage_to_execute['name'] . ' is not a callable function.');
}
return null;
}
/**
* Check if the Queue is in progress
*
* @return bool
*/
public function isQueueInProgress()
{
return
count($this->queue['stages']) &&
(
in_array('NULL', array_column($this->queue['stages'], 'status'), true) ||
in_array('IN_PROGRESS', array_column($this->queue['stages'], 'status'), true)
);
}
/**
* Checks if the queue is over
*
* @return bool
*/
public function isQueueFinished()
{
return ! $this->isQueueInProgress();
}
/**
* Checks if the queue is over
*
* @return bool
*/
public function hasUnstartedStages()
{
if (count($this->queue['stages']) > 0) {
$this->unstarted_stage = array_search('NULL', array_column($this->queue['stages'], 'status'), true);
return is_int($this->unstarted_stage);
}
return false;
}
}